//
// Author 
// Xianguo Lu
// lu@physi.uni-heidelberg.de 
//

#ifndef TEXTXYSUMMARY_H
#define TEXTXYSUMMARY_H

class TextXYSummary
{
 public:
  TextXYSummary(const Int_t istart, const Int_t ny, const TString xtit, const TString ytit[]);
  ~TextXYSummary();

  void AddFile(const TString fin, const TString tag);
  void Write(const TString tag, const Double_t lx0=0.2, const Double_t ly0=0.2, const Double_t lx1=0.8, const Double_t ly1=0.5, const TString opt="p");

  void SetXLimits(const Double_t xmin, const Double_t xmax){fXmin = xmin; fXmax = xmax;};
  void SetYLimits(const Int_t ii, const Double_t ymin, const Double_t ymax){if(ymin<ymax){fYMin[ii]=ymin; fYMax[ii]=ymax;}};

 private:
  void SetGraph(const TString tag="test");
  void SetGraphStyle(TGraph *gtmp, const Int_t ifile);

  Int_t GetMaxNY() const { return sizeof(fGraph[0])/sizeof(TGraph *); }
  Int_t GetMaxNFile() const { return sizeof(fGraph)/sizeof(TGraph *)/GetMaxNY(); }

  //------------------------
  //[ifile][iy]
  TGraph * fGraph[8][10];

  const Int_t fIStart;
  const Int_t fNY;
  Int_t fNFile;

  TString fXTitle;
  TString *fYTitle;

  Int_t *fColor;
  Int_t *fStyle;

  //ymax for different y among files
  Double_t *fYMin;
  Double_t *fYMax;

  Double_t fXmin;
  Double_t fXmax;
};

TextXYSummary::TextXYSummary(const Int_t istart, const Int_t ny, const TString xtit, const TString ytit[])
: fIStart(istart), fNY(ny), fNFile(0)
  , fXTitle(xtit), fYTitle(0x0)
  , fColor(0x0), fStyle(0x0)
  , fXmin(999), fXmax(-999)
{
  gStyle->SetOptTitle(0);

  if(fNY>GetMaxNY()){
    printf("TextXYSummary::TextXYSummary ny>max!! %d %d\n", ny, GetMaxNY()); exit(1);
  }

  for(Int_t iy=0; iy<GetMaxNY(); iy++)
    for(Int_t ifile=0; ifile<GetMaxNFile(); ifile++)
      fGraph[ifile][iy] = 0x0;

  //------------------ y: Set Title ------------------
  //it does NOT work since sizeof(ytit)=sizeof(TString *)
  //const Int_t nyt = sizeof(ytit)/sizeof(TString);

  fYTitle = new TString[fNY];
  for(Int_t iy=0; iy<fNY; iy++){
    fYTitle[iy] = ytit[iy];
  }

  //------------------ file: Set Color and Style ------------------
  fColor = new Int_t[GetMaxNFile()];
  fStyle = new Int_t[GetMaxNFile()];
  const Int_t col[] = {kGreen, kRed, kBlue, kMagenta, kBlack, kRed, kMagenta, kBlue};
  const Int_t sty[] = {22, 23, 20, 21, 29, 28, 25, 30};
  const Int_t nc = sizeof(col)/sizeof(Int_t);
  if(nc<GetMaxNFile()){
    printf("TextXYSummary::TextXYSummary not enough color!! %d %d\n", nc, GetMaxNFile()); exit(1);
  }
  for(Int_t ifile=0; ifile<GetMaxNFile(); ifile++){
    fColor[ifile] = col[ifile];
    fStyle[ifile] = sty[ifile];
  }

  //------------------
  fYMin = new Double_t[fNY];
  fYMax = new Double_t[fNY];
  for(Int_t iy=0; iy<fNY; iy++){
    fYMin[iy] = 1e10;
    fYMax[iy] = -1e10;
  }

}

TextXYSummary::~TextXYSummary()
{
  for(Int_t iy=0; iy<GetMaxNY(); iy++)
    for(Int_t ifile=0; ifile<GetMaxNFile(); ifile++){
      delete fGraph[ifile][iy];
    }

  //delete fYTitle;
  delete fColor;
  delete fStyle;
  delete fYMin;
  delete fYMax;
}

void TextXYSummary::SetGraphStyle(TGraph *gtmp, const Int_t ifile)
{
  //gtmp->GetYaxis()->SetTitleOffset(1.35);
  //gtmp->GetXaxis()->SetTitleOffset(1.25);

  gtmp->SetMarkerSize(2);
  gtmp->SetMarkerColor(fColor[ifile]);
  gtmp->SetLineColor(fColor[ifile]);
  gtmp->SetMarkerStyle(fStyle[ifile]);
}

void TextXYSummary::SetGraph(const TString tag)
{
  for(Int_t iy=0; iy<fNY; iy++){
    TGraph *gtmp = fGraph[fNFile][iy];

    gtmp->SetTitle(tag);
    gtmp->GetXaxis()->SetTitle(fXTitle);
    gtmp->GetYaxis()->SetTitle(fYTitle[iy]);

    SetGraphStyle(gtmp, fNFile);

    //for different ifile
    const Double_t imax = gtmp->GetMaximum();
    const Double_t imin = gtmp->GetMinimum();
    if(imax > fYMax[iy]){
      fYMax[iy] = imax;
    }
    if(imin < fYMin[iy]){
      fYMin[iy] = imin;
    }
  }
}

void TextXYSummary::AddFile(const TString fin, const TString tag)
{
  if(fNFile == GetMaxNFile()){
    printf("TextXYSummary::AddFile nfile == max!! no more space to add %d %d\n", fNFile, GetMaxNFile()); exit(1);
  }

  XGLUtils::ToGraph(fin, fIStart, fNY, fGraph[fNFile]);

  SetGraph(tag);

  fNFile++;
}

void TextXYSummary::Write(const TString otag, const Double_t lx0, const Double_t ly0, const Double_t lx1, const Double_t ly1, const TString opt)
{
  TList *lhard = new TList;
  lhard->SetOwner();

  //no owner
  TList *lsoft = new TList;

  for(Int_t iy=0; iy<fNY; iy++){
    TCanvas *cc=new TCanvas(Form("cc%d",iy));

    TLegend *lg=new TLegend(lx0, ly0, lx1, ly1);
    lg->SetBorderSize(-1);
    lg->SetFillStyle(0);
    lg->SetFillColor(0);
    //lg->SetTextSize(0.04);

    for(Int_t ifile=0; ifile<fNFile; ifile++){

      TGraph *gtmp = fGraph[ifile][iy];

      const Double_t dy = fYMax[iy]-fYMin[iy];
      gtmp->GetYaxis()->SetRangeUser(fYMin[iy]-dy, fYMax[iy]+0.05*dy);
      if(fXmin<fXmax) {
        gtmp->GetXaxis()->SetLimits(fXmin, fXmax);
      }
      gtmp->SetName(Form("gr%d%d",iy, ifile));
      gtmp->Draw(ifile==0?opt+"a":opt);
      lg->AddEntry(gtmp, gtmp->GetTitle(),"p");

      lsoft->Add(gtmp);
    }
    
    lg->Draw("same");

    lhard->Add(lg);
    lhard->Add(cc);
  }

  TFile *fout=new TFile(otag+".root", "recreate");
  fout->cd();
  lhard->Write();
  lsoft->Write();
  fout->Save();
  fout->Write();
  delete fout;

  delete lhard;
  delete lsoft;
}

#endif
